package main;

import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import pojo.Face;

import java.util.ArrayList;
import java.util.List;

/**
 * @Auther:hxn
 * @Date: 2019/5/29 20:07
 * @Description:
 */
public class Run {
    static {
        // 在使用OpenCV前必须加载Core.NATIVE_LIBRARY_NAME类,否则会报错
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }
    public static void main(String[] args) {
        String imgPath =  "D:\\11.jpg";
        String facebookXML = "D:\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml";
        String eyeXML = "D:\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_eye.xml";
        String smileXML = "D:\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_mcs_mouth.xml";
        String noseXML = "D:\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_mcs_nose.xml";
        List<Face> faceList = new ArrayList<>(4);
        faceList.add(new Face(facebookXML,"人脸",255,0,0,2));

        faceList.add(new Face(eyeXML,"眼睛",0,255,0,2));
        faceList.add(new Face(smileXML,"嘴巴",0,0,255,2));
        faceList.add(new Face(noseXML,"鼻子",255,0,255,2));

        //开始识别
        face(imgPath,faceList);
    }


    //faceList：人脸放在第一个
    public static void face(final String imgPath,List<Face> faceList) {
        // 读取测试图片
        Mat image = Imgcodecs.imread(imgPath);
        // 处理人脸部分
        Face facebook = faceList.get(0);
        // 读取OpenCV自带的人脸识别特征XML文件，并识别
        Rect[] rectsFacebook = faceDetectMultiScale(facebook, image);
        //为每张识别到的人脸画一个圈
        for (int j = 0; j < rectsFacebook.length; j++) {
            Imgproc.rectangle(image, new Point(rectsFacebook[j].x, rectsFacebook[j].y),
                    new Point(rectsFacebook[j].x + rectsFacebook[j].width,
                            rectsFacebook[j].y + rectsFacebook[j].height),
                    new Scalar(facebook.getScalarV0(), facebook.getScalarV1(), facebook.getScalarV2()),facebook.getThickness());
            //获取人脸部分的图
            Mat imageFace = new Mat(image,rectsFacebook[j]);
            //处理器官识别
            organDetectMultiScale(faceList,imageFace);
        }
        // 6 展示图片
        HighGui.imshow("人脸识别", image);
        HighGui.waitKey(0);
    }
    //处理器官识别
    public static void organDetectMultiScale(List<Face> faceList,Mat image){
        int size = faceList.size();
        int index = 1;
        for (;index < size;index++)
            circle(faceList.get(index),image);
    }
    //画圆
    public static void circle(Face face,Mat image){
        Rect[] rects = faceDetectMultiScale(face, image);
        System.out.println("匹配到 " + rects.length + " 个"+face.getName());
        // 5 为每张识别到的人脸画一个圈
        for (int i = 0; i < rects.length; i++) {
            Imgproc.rectangle(image, new Point(rects[i].x, rects[i].y),
                    new Point(rects[i].x + rects[i].width, rects[i].y + rects[i].height),
                    new Scalar(face.getScalarV0(), face.getScalarV1(), face.getScalarV2()),face.getThickness());
        }
    }
    //读取OpenCV自带的人脸识别特征XML文件，并识别
    public static Rect[] faceDetectMultiScale(Face face,Mat image){
        CascadeClassifier cacFace = new CascadeClassifier(face.getXml());
        //特征匹配 人脸
        MatOfRect mor = new MatOfRect();
        cacFace.detectMultiScale(image, mor);
        // 4 匹配 Rect 矩阵 数组
        Rect[] rectsFacebook = mor.toArray();
        return rectsFacebook;
    }
}
